/*
 * Copyright (c) 2014 laidian. All Rights Reserved.
 * 
 * @author yaoyuming
 * 
 * @date 2020-03-23 17:20
 */
package com.yao.common.aspect;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.yao.common.helper.RequestHelper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;

/**
 * 日志拦截
 *
 * @author yaoyuming
 * @date 2020/03/23 17:20
 */
@Aspect
@Component
@Slf4j
public class LoggerAspect {

    /**
     * 后缀为.html的不打印日志
     */
    private final static String SUFFIX = ".html";
    /**
     * 记录时间
     */
    private ThreadLocal<Long> startTimeLocal = new ThreadLocal<Long>();

    @Pointcut("execution(public * com.yao..*Controller.*(..))")
    public void webLog() {}

    @Before(value = "webLog()")
    public void deBefore(JoinPoint joinPoint) {
        startTimeLocal.set(System.currentTimeMillis());

        HttpServletRequest request = RequestHelper.getRequest();

        String url = request.getRequestURL().toString();
        if (StrUtil.endWith(url, SUFFIX)) {
            return;
        }

        StringBuffer buffer = new StringBuffer();
        buffer.append("\n");
        buffer.append("[--请求地址--]: ").append(url).append("\n");
        buffer.append("[--请求方法--]: ").append(request.getMethod()).append("\n");
        buffer.append("[--客户端ip--]: ").append(request.getRemoteAddr()).append("\n");
        buffer.append("[--映射方法--]: ").append(joinPoint.getSignature().getDeclaringTypeName()).append(".")
            .append(joinPoint.getSignature().getName()).append("\n");
        buffer.append("[--请求参数--]: ");

        // 判断是否为文件上传
        long length = this.isfileupload(joinPoint);

        if (length > 0) {
            buffer.append("上传文件大小为： " + length);
        } else {
            buffer.append(joinPoint.getArgs() == null ? "" : JSONUtil.toJsonStr(joinPoint.getArgs()));
        }
        buffer.append("\n");

        log.info(buffer.toString());

    }

    @AfterReturning(returning = "object", value = "webLog()")
    public void doAfter(Object object) {

        if (StrUtil.endWith(JSONUtil.toJsonStr(object), SUFFIX)) {
            return;
        }

        StringBuffer buffer = new StringBuffer();
        buffer.append("\n");

        buffer.append("[--响应结果--]: ");

        buffer.append(object == null ? "" : JSONUtil.toJsonStr(object));

        buffer.append("\n");

        buffer.append("[--执行耗时--]: ").append(System.currentTimeMillis() - startTimeLocal.get()).append(" ms")
            .append("\n");

        log.info(buffer.toString());

    }

    /**
     * 判断是否文件上传。文件上传时返回文件大小，否则返回-1
     *
     * @param joinPoint
     * @return
     */
    private long isfileupload(JoinPoint joinPoint) {

        Object[] args = joinPoint.getArgs();

        if (args == null || args.length == 0) {
            return -1;
        }

        for (Object arg : args) {
            if (arg == null) {
                continue;
            }

            if (arg instanceof MultipartFile) {
                long size = ((MultipartFile)arg).getSize();
                return size;
            }
        }

        return -1;
    }

}